Visual Form

Design is a requirement, not a cosmetic addition.


  • Nützlichkeit
  • Effizienz
  • Ästhetik

Foto von Samuel Scrimshaw auf Unsplash

Setup

# install.packages(c("here", "ggwordcloud", "ggrepel", "ggtext", "showtext", "tidyverse", "paletteer", "ggthemes"))

library(here)
#library(janitor)
library(ggwordcloud)
library(ggrepel)
library(ggtext)
library(showtext)
library(tidyverse)
library(paletteer)
library(ggthemes)


gapminder <- readRDS(here::here("data", "gapminder_dat.rds"))

gapminder_europe <- gapminder %>%
  filter(world_4region == "europe", time >= 1900, time <= 2024) %>%
  drop_na(gini)

gapminder_2020 <- gapminder %>%
  filter(time == 2020) %>%
  drop_na(world_6region, world_4region, country, gini, hapiscore_whr) %>%
  arrange(desc(co2_cons))

Der Ausgangsplot für diese Session: Wiederholung

Erstelle einen Plot der den Gini-Koeffizienten (gini) gegen den Happiness-Score (hapiscore_whr) in verschiedenen Ländern 2020 (gapminder_2020) darstellt. Der Plot sollte einen Scatterplot enthalten, und eine geglättete Linie (geom_smooth()). Füge außerdem Titel und Achsenbeschriftungen hinzu.

Link zum Setup, falls nötig

ggplot(
  data = gapminder_2020,
  mapping = aes(
    x = gini,
    y = hapiscore_whr
  )
) +
  geom_point() +
  geom_smooth() +
  labs(
    title = "Ungleichheit = Un-Happiness?",
    subtitle = "Gini-Koeffizient und Happiness-Score in verschiedenen Ländern 2020",
    x = "Gini-Index",
    y = "Happiness-Score",
  ) +
  theme_bw()

Salienz von Informationen

 

Durch die Unterscheidbarkeit von grafischen Symbolen (visual features) soll grafische Informationen möglichst schnell aufgenommen werden, ohne lange überlegen zu müssen.

Dafür können die sog. Gestalt-Prinzipien genutzt werden.

Gestalt-Prinzipien

Menschen nehmen Muster nach gewissen Prinzipien wahr. Die Regeln, nach denen wir Muster wahrnehmen, werden Gestalt-Prinzipien genannt, beispielsweise:

  • Nähe: Einander nahe Elemente werden als zusammengehörig wahrgenommen
  • Ähnlichkeit: Einander ähnliche Elemente werden als zusammengehörig wahrgenommen
  • Verbundene Elemente: Verbundene Elemente werden als zusammengehörig wahrgenommen
  • Gute Fortsetzung: Linien werden wahrgenommen, als folgten sie dem einfachsten Weg
  • Geschlossenheit: Unvollständige Elemente werden als vollständig wahrgenommen
  • Figur und Grund: Elemente sind entweder im Vorder- oder Hintergrund
  • Gemeinsames Schicksal: Elemente mit ähnlicher Bewegungsrichtung werden als zusammengehörig wahrgenommen

Salienz

Salienz durch visual features:

Abbildung von Wong, B. (2010)

Gruppieren

Gruppierung durch Form

Gruppierung durch verbundene Elemente

Gruppieren durch Nähe

Darstellung von Größen

Die Größe von Elemenen kann auch genutzt werden, um Daten zu kodieren.

Gruppierung durch Form

ggplot(
  data = gapminder_2020,
  mapping = aes(
    x = gini,
    y = hapiscore_whr
  )
) +
  geom_point(aes(shape = world_4region)) +
  geom_smooth() +
  labs(
    title = "Ungleichheit = Un-Happiness?",
    subtitle = "Gini-Koeffizient und Happiness-Score in verschiedenen Ländern 2020",
    x = "Gini-Index",
    y = "Happiness-Score",
  ) +
  theme_bw()

Darstellung von Größen

Erweitert den Plot aus der vorherigen Übung, indem ihr die Punkte nach Weltregion (world_4region) einfärbt. Erweitert den Plot um die Aesthetic size, sodass sich die Größe der Punkte nach der Bevölkerungsgröße (pop) richtet.

Link zum Setup, falls nötig

ggplot(
  data = gapminder_2020,
  mapping = aes(
    x = gini,
    y = hapiscore_whr
  )
) +
  geom_point(aes(color = world_4region, size = pop)) +
  geom_smooth() +
  labs(
    title = "Ungleichheit = Un-Happiness?",
    subtitle = "Gini-Koeffizient und Happiness-Score in verschiedenen Ländern 2020",
    x = "Gini-Index",
    y = "Happiness-Score",
  ) +
  theme_bg()

Darstellen von Größen

ggplot(
  data = gapminder_2020,
  mapping = aes(
    x = gini,
    y = hapiscore_whr
  )
) +
  geom_point(aes(color = world_4region, size = pop)) +
  geom_smooth() +
  labs(
    title = "Ungleichheit = Un-Happiness?",
    subtitle = "Gini-Koeffizient und Happiness-Score in verschiedenen Ländern 2020",
    x = "Gini-Index",
    y = "Happiness-Score",
  ) +
  theme_bw()

Einschätzen von Größen

Die Größe von Kreisen einzuschätzen ist schwer!

Datenumwandlung für den folgenden Teil

continent_co2 <- gapminder_2020 %>%
  group_by(world_6region) %>%
  summarise(mean_co2_pcap_cons = mean(co2_pcap_cons, na.rm = TRUE)) %>%
  drop_na(mean_co2_pcap_cons)

continent_co2_pct <- continent_co2 %>%
  mutate(percentage = mean_co2_pcap_cons / sum(mean_co2_pcap_cons) * 100)

Das gleiche gilt für Winkel!

Versuche, die Größen zu sortieren:

Das gleiche gilt für Winkel!

Kreis- bzw. Tortendiagramme sollten daher vermieden werden.

Farbe

Farbe ist eine der wichtigsten Methoden, um Informationen zu labeln, hervorzuheben, Werte zu kommunizieren, Realität simulieren, und um zu designen und zu dekorieren.

Foto von Efe Kurnaz auf Unsplash

Kategoriale vs. quantitative Daten

Kategoriale Daten

Verschiedene Farben, die sich gut unterscheiden lassen.

Quantitative Daten

Farbverläufe, die eine Reihenfolge haben.

Skalenarten

Bild von nature methods.

Farbwahrnehmung beim Menschen

Primärfarben des Lichts: Rot, Grün, Blau


By Original: Penubag Vector: Victor Blacus - Own work based on: Electromagnetic-Spectrum.png, CC BY-SA 3.0, Link
By BenRG - Own work, Public Domain, Link

Andere Tiere können auch mal mehr oder weniger haben:

Bild aus Farbsehen der Tiere
Foto von Ben Moreland auf Unsplash

Viele Tiere sehen nur grau

Warum überhaupt Farbwahrnehmung?

  • Konsistenz: Farbtöne sind unabhängig vom Licht wahrnehmbar.
  • Aber: More is not always better! Zu viel kann auch vom Wesentlichen ablenken.

Farbwahrnehmung ist also subjektiv, und bringt nur einen Vorteil, wenn eine Bedeutung daraus abgeleitet werden kann.

Foto von Chinh Le Duc auf Unsplash

More is not always better

Mehr als sechs Farben sollten es auf keinen Fall werden!

Alternative: Facetting.

Farbe ist relativ

Ganglienzellen übertragen keine Informationen über absolute Helligkeit, sondern über relative Helligkeit.

Visualisierung kann nicht gut darin sein, absolute Werte zu kommunizieren (Tabellen können das besser). Aber: Unterschiede und Veränderungen.

Bild von Nature Methods.

Farbe ist relativ

Hier sind die Farben klar unterscheidbar, und der Gini-Index lässt sich gut ablesen.

Hier werden die tatsächlichen Werte des Gini-Index nicht gut kommuniziert.

Farbe ist relativ

Eigenschaften von Farben

Farbton, Sättigung, Helligkeit

Die drei Eigenschaften beschreiben das Aussehen von Farben.

Farbräume

  • RGB: Zusammenmischen von Licht der unterschiedlichen Farben. Alle drei zusammen ergeben weiß.
  • CMYK: Ausblenden aus dem weißen Farbspektrum durch Filter. Grundfarben: Gelb, Magenta (Purpur), Cyan (Blaugrün) (+K - Key (also Schwarz))

Salienz

Sticht eine Farbe hervor, ist sie besonders salient - das kann gewollt oder ungewollt sein.

Größe

Farbfehlsichtigkeit

  • Protanopie: Zapfentyp L (rot) fehlt: rot vs grün Schwäche
  • Deuteranopie: Zapfentyp M (grün) fehlt: rot vs grün Schwäche
  • Tritanopie: Zapfentyp S (blau) fehlt: blau vs grün, gelb vs violett Schwäche

Rechts: Protanopie

By Mark Fairchild, CC BY-SA 3.0, Link

Colorblind-Check

Auf Colblindor.

Mit colorblindcheck.

library(colorblindcheck)

palette_check(c("#F8766D", "#B79F00", "#00BA38", "#00BFC4", "#619CFF", "#F564E3"), plot = TRUE)

          name n tolerance ncp ndcp  min_dist mean_dist max_dist
1       normal 6  28.22768  15   15 28.227682  48.60479 91.99894
2 deuteranopia 6  28.22768  15    9  5.870477  31.50134 59.55026
3   protanopia 6  28.22768  15    8  3.930855  32.79118 57.04317
4   tritanopia 6  28.22768  15    9  7.200490  40.41105 71.61725

Farben wählen

  • Name: "red"
  • rgb(): rgb(1,0,0)
  • Hex code: #FF0000
ggplot(
  gapminder_2020,
  aes(x = gini, y = hapiscore_whr)
) +
  geom_point(size = 3, color = "#FF0000") +
  geom_smooth(color = "darkgreen") +
  theme_bg()

Farben manuell setzen

ggplot(
  continent_co2_pct,
  aes(
    x = world_6region,
    y = percentage,
    fill = world_6region
  )
) +
  geom_bar(stat = "identity", width = 1) +
  theme_minimal() +
  labs(title = "Share of global per capita CO2 consumption") +
  scale_fill_manual(values = c("red", "green", "blue", "yellow", "violet", "brown"))

my_color_scale <- c(
  "East Asia & Pacific" = "red",
  "South Asia" = "green",
  "Sub-Saharan Africa" = "blue",
  "Europe & Central Asia" = "yellow",
  "Middle East & North Africa" = "violet",
  "Americas" = "brown"
)

ggplot(
  continent_co2_pct,
  aes(
    x = world_6region,
    y = percentage,
    color = world_6region
  )
) +
  geom_bar(stat = "identity", width = 1) +
  theme_minimal() +
  labs(title = "Share of global per capita CO2 consumption 2020") +
  scale_color_manual(values = my_color_scale)

Wenn du in einem Projekt die gleichen Gruppen in verschiedenen Plots zeigst, setze die Farbskala einmal mit den Gruppennamen, damit die Gruppen in allen Plots die selben Farben bekommen.

Graustufen

ggplot(
  continent_co2_pct,
  aes(
    x = world_6region,
    y = percentage,
    fill = world_6region
  )
) +
  geom_bar(stat = "identity", width = 1) +
  theme_minimal() +
  labs(title = "Share of global per capita CO2 consumption 2020") +
  scale_fill_grey()

Externe Farb-Paletten

R Color Brewer

library(RColorBrewer)
display.brewer.all(colorblindFriendly = FALSE)

library(RColorBrewer)

ggplot(
  continent_co2_pct,
  aes(
    x = world_6region,
    y = percentage,
    fill = world_6region
  )
) +
  geom_bar(stat = "identity", width = 1) +
  theme_minimal() +
  labs(title = "Share of global per capita CO2 consumption") +
  scale_fill_brewer(palette = "PuOr")

Externe Farb-Paletten

paletteer

Sammlung von Paletten aus diversen Paketen

Z.B. Enthält "lisa::Jean_MichelBasquiat_1" folgende Farben:

 paletteer::paletteer_d("lisa::Jean_MichelBasquiat_1") 
<colors>
#C11432FF #009ADAFF #66A64FFF #FDD10AFF #070707FF 
library(paletteer)

ggplot(
  continent_co2_pct,
  aes(
    x = world_6region,
    y = percentage,
    fill = world_6region
  )
) +
  geom_bar(stat = "identity", width = 1) +
  theme_minimal() +
  labs(title = "Share of global per capita CO2 consumption") +
  scale_fill_paletteer_d("lisa::Jean_MichelBasquiat_1")

Wechsel die Farbpalette für den Übungsplot und teste sie auf Farbfehlsichtigkeiten.

Link zum Setup, falls nötig

ggplot(
  data = gapminder_2020,
  mapping = aes(
    x = gini,
    y = hapiscore_whr
  )
) +
  geom_point(aes(color = world_4region, size = pop)) +
  geom_smooth() +
  labs(
    title = "Ungleichheit = Un-Happiness?",
    subtitle = "Gini-Koeffizient und Happiness-Score in verschiedenen Ländern 2020",
    x = "Gini-Index",
    y = "Happiness-Score",
  ) +
  theme_bw()

ggplot(
  data = gapminder_2020,
  mapping = aes(
    x = gini,
    y = hapiscore_whr
  )
) +
  geom_point(aes(color = world_4region, size = pop)) +
  geom_smooth() +
  labs(
    title = "Ungleichheit = Un-Happiness?",
    subtitle = "Gini-Koeffizient und Happiness-Score in verschiedenen Ländern 2020",
    x = "Gini-Index",
    y = "Happiness-Score",
  ) +
  theme_bw() +
  paletteer::scale_colour_paletteer_d("lisa::FridaKahlo")

palette_check(paletteer::paletteer_d("lisa::FridaKahlo"), 
              plot = TRUE)

          name n tolerance ncp ndcp  min_dist mean_dist max_dist
1       normal 5  19.20737  10   10 19.207369  40.81006 72.81425
2 deuteranopia 5  19.20737  10    8  1.160009  33.73234 73.34852
3   protanopia 5  19.20737  10    7  9.881437  34.30690 72.28313
4   tritanopia 5  19.20737  10    9 18.518051  39.51372 72.61195

Funktionelles Desing

Funktionelles Desing

Foto von Kelly Sikkema auf Unsplash
Foto von Yucel Moran auf Unsplash

Hier gilt ganz besonders: Simplify to Clarify

Funktionelles Design

Foto von BVG

Foto von BVG

Dabei kann es helfen, sich von bereits vorhandenen Plots inspirieren zu lassen.
Handschriftliche Skizze ist auch erstmal hilfreich!

Simplify to clarify: Data-ink ratio

Data graphics should draw the viewer’s attention to the sense and substance of the data, not to something else.

Tufte & Graves-Morris (1983)



Data-ink ratio = Data-ink / Total ink used to print the graphic

Jedes Stück Tinte sollte einen Grund haben.

Data-ink ratio in Praxis

10% Daten, 90 % Achsenbeschriftungen und Hintergrundlinien

library(ggthemes)

ggplot(
  data = gapminder_2020,
  mapping = aes(x = gini, y = hapiscore_whr, color = world_4region)
) +
  geom_point() +
  theme_excel() +
  scale_x_continuous(
    breaks = scales::pretty_breaks(n = 10), # ensure ticks
    minor_breaks = waiver() # ensures minor ticks too
  ) +
  scale_y_continuous(
    breaks = scales::pretty_breaks(n = 10),
    minor_breaks = waiver()
  ) +
  theme(
    panel.grid.major = element_line(color = "grey60", size = 1.2), # thick major grid
    panel.grid.minor = element_line(color = "grey60", size = 0.8) # thick minor grid
  )

0% Daten (Plotte die Daten, keine Zusammenfassungen)

ggplot(
  data = gapminder_2020,
  mapping = aes(x = gini, y = hapiscore_whr, color = world_4region)
) +
  geom_smooth()

ca. 90 % Daten, 10 % Achsenbeschriftungen und Legende

library(ggthemes)
ggplot(
  data = gapminder_2020,
  mapping = aes(x = gini, y = hapiscore_whr, color = world_4region)
) +
  geom_point() +
  theme_tufte()

Redundanzen

Erase non-data-ink, within reason. Erase redundant data-ink, within reason.

Tufte & Graves-Morris (1983)

Auf wie viele Arten wird hier die Höhe der CO2 Emissionen pro Kopf dargestellt?

Auf sieben verschiedene Arten:

  1. Höhe der linken Balkenlinie
  2. Höhe der rechten Balkenlinie
  3. Höhe der horizontalen Balkenlinie
  4. Höhe des Balkeninneren
  5. Farbe des Balkens
  6. Position des Labels
  7. Wert des Labels

Balken an sich enthalten also schon redundante Informationen!

Tufte-Konformer Barplot

Entfernen der Achsenlinien und Umrandungen. Hintergrundlinien werden innerhalb der Balken dargestellt.

library(ggthemes)

ggplot(
  gapminder_2020[1:10, ],
  aes(x = reorder(country, co2_pcap_cons), y = co2_pcap_cons)
) +
  geom_bar(stat = "identity", width = 0.5, color = NA, fill = "grey") +
  geom_hline(yintercept = seq(0, 30, by = 5), color = "white", size = 0.3) +
  theme(axis.text.x = element_text(angle = 90, hjust = 1), axis.ticks = element_blank()) +
  labs(
    x = "Land",
    y = "CO2 Consumption per capita in t"
  ) +
  theme_tufte()

Mitunter können die vertikalen und horizontalen Linien auch hilfreich beim Vergleich/bei der Zuordnung zum Land sein.

library(ggplot2)

ggplot(
  gapminder_2020[1:10, ],
  aes(x = reorder(country, co2_pcap_cons), y = co2_pcap_cons)
) +
  # vertikale Linie, leicht nach links geschoben
  geom_segment(
    aes(xend = reorder(country, co2_pcap_cons), y = 0, yend = co2_pcap_cons),
    position = position_nudge(x = -0.14)
  ) +
  geom_segment(aes(
    x = as.numeric(reorder(country, co2_pcap_cons)) - 0.15,
    xend = as.numeric(reorder(country, co2_pcap_cons)) + 0.15,
    y = co2_pcap_cons, yend = co2_pcap_cons
  )) +
  ylim(c(0, 30)) +
  labs(
    x = "Land",
    y = "CO2 Consumption per capita in t"
  ) +
  theme_tufte() +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

::: :::

Maximieren von Informationen

Normaler Scatterplot

Box um den Plot, Grid-Linien, Achsen-Ticks: Alles keine Daten.

ggplot(
  data = gapminder_2020,
  mapping = aes(x = gini, y = hapiscore_whr, color = world_4region)
) +
  geom_point()

Tufte-Scatterplot

Nutzen der Ticks und Achsen-Linien, um Informationen zu transportieren.

library(paletteer)


xlim_v <- c(20, 80)
ylim_v <- c(20, 80)

# Parameter: Anzahl der Quantile, Versatz von den Rändern, kleine Lücke zwischen Segmenten
probs <- seq(0, 1, by = 0.25) # Quartile; für Dezile: by = 0.1
off_x <- 0 # Versatz der "y-Achse" nach rechts
off_y <- 0 # Versatz der "x-Achse" nach oben
gap <- 0.2 # kleine Lücke an Segmentenden (optisch schöner)

qx <- quantile(gapminder_2020$gini, probs = probs, na.rm = TRUE)
qy <- quantile(gapminder_2020$hapiscore_whr, probs = probs, na.rm = TRUE)

# Segment-Dataframes bauen (pro Intervall ein Segment)
seg_x <- tibble(
  x    = pmax(qx[-length(qx)] + gap / 2, xlim_v[1]),
  xend = pmin(qx[-1] - gap / 2, xlim_v[2]),
  y    = ylim_v[1] + off_y,
  yend = ylim_v[1] + off_y
) %>% filter(x < xend)

seg_y <- tibble(
  x    = xlim_v[1] + off_x,
  xend = xlim_v[1] + off_x,
  y    = pmax(qy[-length(qy)] + gap / 2, ylim_v[1]),
  yend = pmin(qy[-1] - gap / 2, ylim_v[2])
) %>%
  filter(y < yend)

ggplot(
  data = gapminder_2020,
  mapping = aes(x = gini, y = hapiscore_whr, color = world_4region)
) +
  geom_point() +
  # Quantil-"x-Achse" (horizontal) leicht ins Panel versetzt
  geom_segment(
    data = seg_x,
    aes(x = x, xend = xend, y = y, yend = yend),
    inherit.aes = FALSE
  ) +
  # Quantil-"y-Achse" (vertikal) leicht ins Panel versetzt
  geom_segment(
    data = seg_y,
    aes(x = x, xend = xend, y = y, yend = yend),
    inherit.aes = FALSE
  ) +
  scale_x_continuous(breaks = unique(c(round(seg_x$x, 0), round(seg_x$xend, 0)))) +
  scale_y_continuous(breaks = unique(c(round(seg_y$y, 0), round(seg_y$yend, 0)))) +
  coord_cartesian(xlim = xlim_v, ylim = ylim_v, expand = FALSE) +
  theme_tufte() +
  theme(axis.ticks = element_blank()) +
  paletteer::scale_colour_paletteer_d("fishualize::Koumansetta_rainfordi")

Verteilungen Plotten




Reduzieren heißt nicht, die Informationen zu reduzieren, sondern den Chart-Junk!
Sehr oft macht es Sinn, die gesamte Verteilung zu plotten, möglicherweise auch zusätzlich zu zusammenfassenden Statistiken.

Verteilungen plotten

Boxplot

ggplot(
  data = gapminder_2020 %>% drop_na(country),
  aes(x = world_4region, y = hapiscore_whr, fill = world_4region)
) +
  geom_boxplot() +
  theme(axis.ticks = element_blank(), legend.position = "none") +
  scale_fill_paletteer_d("fishualize::Koumansetta_rainfordi") +
  xlab("Region") +
  ylab("Happiness Score (World Happiness Report)")

Tufte-Boxplot

library(ggthemes)

ggplot(
  data = gapminder_2020 %>% drop_na(country),
  aes(x = world_4region, y = hapiscore_whr, group = world_4region)
) +
  geom_jitter(alpha = 0.5, color = "lightgrey", height = 0) +
  geom_tufteboxplot() +
  scale_fill_paletteer_d("fishualize::Koumansetta_rainfordi") +
  xlab("Region") +
  ylab("Happiness Score (World Happiness Report)") +
  theme_tufte()

Zusammenfassung



  1. Above all else show the data.
  2. Maximize the data-ink ratio, within reason.
  3. Erase non-data-ink, within reason.
  4. Erase redundant data-ink, within reason.
  5. Revise and edit.

Aus Tufte & Graves-Morris (1983).

Design

Design

Abbildung von [Cédric Scherer]https://www.behance.net/gallery/100683383/Travelling-to-Outer-Space#).

Farben als Design-Element

All colors are the friends of their neighbors and the lovers of their opposites. - Marc Chagall

Nach MalteAhrens at de.wikipedia. Vectorization by User:SidShakal - Raster version from Wikimedia Commons., Gemeinfrei, Link

Kleine Farbenlehre

Vincent van Gogh, Public domain, via Wikimedia Commons

  • Gegenüberliegende Farben intensivieren sich gegenseitig: eine Primärfarbe, und eine Sekundärfarbe, die aus den anderen beiden Primärfarben gemischt wird. Das erzeugt stärkere Kontraste.
  • Mit weiß und schwarz lassen sich die Schattierungen hinzumischen.

Weitere Tools

Wollbox von Vincent van Gogh, mit der er Farbkombinationen getestet hat. Eigenes Bild.

Schriften

Die Schriftart kann einer Abbildung ein ganz anderes Aussehen verleihen.
Wir nutzen Schriftarten von Google Fonts.

library(showtext)

font_add_google("Special Elite", family = "special")

Foto von Natalia Y. auf Unsplash

Schriftart

library(ggwordcloud)

tags <- read.csv(here::here("data", "goodbooks-10k", "tags.csv"))
book_tags <- read.csv(here::here("data", "goodbooks-10k", "book_tags.csv"))
books <- read.csv(here::here("data", "goodbooks-10k", "books.csv"))


classics <- book_tags %>%
  left_join(books) %>%
  left_join(tags) %>%
  filter(tag_name == "classics") %>%
  filter(ratings_count > 20000, !duplicated(authors)) %>%
  select(original_title, average_rating, tag_name, ratings_count) %>%
  distinct() %>%
  arrange(ratings_count) %>%
  slice_tail(n = 50)


set.seed(45)
ggplot(
  data = classics,
  mapping = aes(label = original_title, size = average_rating)
) +
  geom_text_wordcloud() +
  scale_size(range = c(1, 6)) +
  labs(
    title = "What to read next ...",
    subtitle = "... according to goodreads"
  ) +
  theme_bg()

Daten von zygmuntz.

Schriftart

font_add_google("Special Elite", family = "my textfont")
font_add_google("Playfair Display")

showtext_auto()


set.seed(45)
ggplot(
  data = classics,
  mapping = aes(label = original_title, size = average_rating)
) +
  geom_text_wordcloud(family = "my textfont") +
  scale_size(range = c(1, 6)) +
  labs(
    title = "What to read next",
    subtitle = "According to goodreads"
  ) +
  theme_bg() +
  theme(title = element_text(family = "Playfair Display", size = 20))

Suche dir eine Schriftart aus Google Fonts und baue sie in den Übungs-Plot ein.

Link zum Setup, falls nötig

ggplot(
  data = gapminder_2020,
  mapping = aes(
    x = gini,
    y = hapiscore_whr
  )
) +
  geom_point(aes(color = world_4region, size = pop)) +
  geom_smooth() +
  labs(
    title = "Ungleichheit = Un-Happiness?",
    subtitle = "Gini-Koeffizient und Happiness-Score in verschiedenen Ländern 2020",
    x = "Gini-Index",
    y = "Happiness-Score",
  ) +
  theme_bw() +
  paletteer::scale_colour_paletteer_d("lisa::FridaKahlo") 

font_add_google("Special Elite", family = "my textfont")
font_add_google("Playfair Display")

showtext_auto()

ggplot(
  data = gapminder_2020,
  mapping = aes(
    x = gini,
    y = hapiscore_whr
  )
) +
  geom_point(aes(color = world_4region, size = pop)) +
  geom_smooth() +
  labs(
    title = "Ungleichheit = Un-Happiness?",
    subtitle = "Gini-Koeffizient und Happiness-Score in verschiedenen Ländern 2020",
    x = "Gini-Index",
    y = "Happiness-Score",
  ) +
  theme_bw() +
  paletteer::scale_colour_paletteer_d("lisa::FridaKahlo") +
  theme(
    title = element_text(family = "Playfair Display"), ## ändert alle Titel im Plot
    legend.title = element_text(family = "my textfont", size = 12), ## ändert nur den Legenden-Titel
    legend.text  = element_text(family = "Playfair Display", size = 10) ## ändert nur den Legenden-Text
  )

Literatur

Tufte, E. R., & Graves-Morris, P. R. (1983). The visual display of quantitative information (Bd. 2). Graphics press Cheshire, CT.